import React, { useState, useEffect, useRef } from 'react';
import { PropTypes } from 'prop-types';
import {
  Switch,
  Route,
  Redirect,
  useHistory,
  useLocation
} from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { BlankPage } from '@shell-ui/components';
import SideNavigation from './components/side-navigation';
import { actions } from './store';
import useServiceLoader from './utils/useServiceLoader';
import Home from './views/home';

const AppContent = (props) => {
  const { routes, registed, setRegisted } = props;
  const dispatch = useDispatch();
  const { registeredApps, apps, currentApp } = useSelector(state => state.global);
  const registeredAppsRef = useRef(registeredApps);
  useEffect(() => {
    registeredAppsRef.current = registeredApps;
  }, [registeredApps]);

  const [serviceStatus, setServiceStatus] = useState({ loaded: false });

  const statusHandler = ({ status, msg }, name) => {
    const loaded = status !== 'processing' || status !== 'failed';
    setServiceStatus({
      loaded,
      status,
      msg,
      name
    });
  };

  useEffect(() => {
    if (registed) {
      dispatch(actions.setCurrentApp({ status: 'success' }));
      statusHandler({ status: 'success' });
      setRegisted(false);
    }
  }, [registed]);

  const [loadService] = useServiceLoader(apps, statusHandler);
  const onLoadService = async (path) => {
    setServiceStatus({
      loaded: false
    });

    const pathname = path.slice(1).split('/')[0];
    const app = apps.find(item => item.pathPrefix === pathname);
    if (!app) {
      return statusHandler({ status: 'failed', }, 'failed');
    }

    const appName = app.module;
    if (registeredAppsRef.current.includes(appName)) {
      currentApp.name !== appName && dispatch(actions.setCurrentApp({ ...app }));
      return setServiceStatus({
        loaded: true,
        name: appName
      });
    }
    dispatch(actions.setCurrentApp({ status: 'loading'}));
    const result = await loadService(appName);
    if (result) {
      dispatch(actions.setCurrentApp({ status: result.status }));
      return statusHandler(result, appName);
    }
  };

  const [pathname, setPathname] = useState('');
  const history = useHistory();
  const location = useLocation();
  useEffect(() => {
    onLoadService(location.pathname);
    setPathname(location.pathname);
    return history.listen((current) => {
      onLoadService(current.pathname);
      setPathname(current.pathname);
    });
  }, []);

  return (
    <div id="app-wrapper">
      <SideNavigation
        data={apps}
        pathname={pathname}
        currentApp={currentApp}
      />
      <div className="nav-content" id="app-module">
        <Switch>
          <Route key="root" path="/" render={() => (<Redirect to="/home" />)} replace exact />
          <Route key="home" path="/home"><Home /></Route>
          {routes}
          <Route key={'not-matched-page'} replace>
            <BlankPage
              key={serviceStatus.name}
              code={serviceStatus.loaded ? 404 : 302}
            >
              {serviceStatus.msg}
            </BlankPage>
          </Route>
        </Switch>
      </div>
    </div>
  )
};

AppContent.propTypes = {
  routes: PropTypes.array,
  registed: PropTypes.bool,
  setRegisted: PropTypes.func
};

AppContent.defaultProps = {
  routes: [],
  registed: false,
  setRegisted: () => {}
};

export default AppContent;
